package com.toy.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.api.R;
import com.toy.entity.Product;
import com.toy.entity.ProductCategory;
import com.toy.mapper.ProductCategoryMapper;
import com.toy.mapper.ProductMapper;
import com.toy.service.ProductCategoryService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.toy.vo.ProductCategoryVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author admin
 * @since 2022-08-31
 */
@Service
public class ProductCategoryServiceImpl extends ServiceImpl<ProductCategoryMapper, ProductCategory> implements ProductCategoryService {

    @Autowired
    private ProductCategoryMapper productCategoryMapper;
    @Autowired
    private ProductMapper productMapper;

    /**
     * 构建商品分类菜单
     * @return
     */
    @Override
    public List<ProductCategoryVO> buildProductCategoryMenu() {
        //1、查询所有的商品分类数据
        List<ProductCategory> productCategoryList = this.productCategoryMapper.selectList(null);

        //2、数据类型转换ProductCategoryVO
        List<ProductCategoryVO> productCategoryVOList = productCategoryList.stream().
                map(ProductCategoryVO::new).collect(Collectors.toList());
        //3、进行父子级菜单的封装
        List<ProductCategoryVO> levelOneList = buildMenu(productCategoryVOList);
        //4、查找一级分类对应的商品信息
        getLevelOneProduct(levelOneList);
        return levelOneList;
    }

    @Override
    public List<ProductCategoryVO> findAllProductByCategoryLevelOne() {
        QueryWrapper<ProductCategory> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("type", 1);
        List<ProductCategory> productCategoryList = this.productCategoryMapper.selectList(queryWrapper);
        List<ProductCategoryVO> productCategoryVOList = productCategoryList.stream().map(ProductCategoryVO::new).collect(Collectors.toList());
        getLevelOneProduct(productCategoryVOList);
        return productCategoryVOList;
    }


    /**
     * 查找一级分类对应的商品信息
     */
    public void getLevelOneProduct(List<ProductCategoryVO> levelOneList){
        for (ProductCategoryVO vo : levelOneList) {
            QueryWrapper<Product> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("categorylevelone_id", vo.getId());
            List<Product> productList = this.productMapper.selectList(queryWrapper);
            vo.setProductList(productList);
        }
    }

    /**
     * 构建菜单
     * @param productCategoryVOList
     */
    public List<ProductCategoryVO> buildMenu(List<ProductCategoryVO> productCategoryVOList){
        //找到一级菜单
        List<ProductCategoryVO> levelOneList = productCategoryVOList.stream().filter(c -> c.getParentId() == 0).collect(Collectors.toList());
        for (ProductCategoryVO productCategoryVO : levelOneList) {
            recursion(productCategoryVOList,productCategoryVO);
        }
        return levelOneList;
    }

    /**
     * 递归分类
     */
    public void recursion(List<ProductCategoryVO> list,ProductCategoryVO productCategoryVO){
        //找到子菜单
        List<ProductCategoryVO> children = getChildren(list, productCategoryVO);
        productCategoryVO.setChildren(children);
        //继续查找子菜单
        if (children.size() > 0){
            for (ProductCategoryVO vo : children) {
                recursion(list, vo);
            }
        }
    }

    /**
     * 获取子菜单
     * @param list
     * @param productCategoryVO
     */
    public List<ProductCategoryVO> getChildren(List<ProductCategoryVO> list,ProductCategoryVO productCategoryVO){
        ArrayList<ProductCategoryVO> children = new ArrayList<>();
        Iterator<ProductCategoryVO> iterator = list.iterator();
        while (iterator.hasNext()){
            ProductCategoryVO next = iterator.next();
            if (next.getParentId().equals(productCategoryVO.getId())){
                children.add(next);
            }
        }
        return children;
    }


    /**
     * 根据传入的type 查询的级别，返回相应的 类别（嵌套）
     * <p>
     * level查询级别
     * 1 查询一级分类
     * 2 查询 1-2 级商品分类
     * 3 查询 1-2-3 级商品分类
     * <p>
     * 业务说明: 查询 3 级分类菜单数据 要求三层结构嵌套
     *
     * @param type
     * @return
     */
    @Override
    public List<ProductCategory> findItemCatList(Integer type) {
        // 将所有的ItemCat对象，封装到Map中
        Map<Integer, List<ProductCategory>> map = getMap();
        // 从Map，取相应的类别
        if (type == 1) return map.get(0); // 获取一级类别
        if (type == 2) return findTwoCatList(map);
        List<ProductCategory> threeCatList = findThreeCatList(map);
        return threeCatList;
    }




    public void saveItemCat(ProductCategory itemCat) {
        productCategoryMapper.insert(itemCat);
    }


    public void updateItemCat(ProductCategory itemCat) {
        productCategoryMapper.updateById(itemCat);
    }


    @Transactional
    public void deleteItemCat(ProductCategory itemCat) {
        QueryWrapper<ProductCategory> queryWrapper =null;
        //1.判断等级是否为3级
        if (itemCat.getType() == 3){
            productCategoryMapper.deleteById(itemCat.getId());
        }else if (itemCat.getType() == 2) {//2.判断等级是否为2级
            //2.1先删除那些拿着我的id，作为parent_idde类别（3级类别）
            //2.2再删除自己(当前2级类别）
            queryWrapper = new QueryWrapper();
            queryWrapper.eq("parent_id", itemCat.getId());
            productCategoryMapper.delete(queryWrapper);
            productCategoryMapper.deleteById(itemCat.getId());
        }else {//3.判断等级是否为1级
            //3.1、查出所有二级分类
            queryWrapper = new QueryWrapper();
            queryWrapper.eq("parent_id", itemCat.getId());
            List<ProductCategory> twoList = productCategoryMapper.selectList(queryWrapper);
            //3.2、查出三级类别
            for (ProductCategory ic : twoList) {
                queryWrapper.clear();
                queryWrapper.eq("parent_id", ic.getId());//查询三级类别
                productCategoryMapper.delete(queryWrapper);//删除三级类别
                productCategoryMapper.deleteById(ic.getId());//删除二级类别
            }
            productCategoryMapper.deleteById(itemCat.getId());//删除一级级类别
        }

    }

    /**
     * 1. 只查询一次数据库
     * 2. 将数据保存到：Map<Integer, List<ItemCat>>
     * key是 parent_id
     * value是 一个List集合
     * 3. 向Map中添加一个类别对象
     * * 3.1 先查询 类别对象的parent_id，在Map是否存在
     * * 3.2 如果有，取出对应的List，向其中保存当前的ItemCat对象
     * * 3.3 如果没有，创建一个List
     * * 将ItemCat对象保存到该list中
     * * 再将<parent_id, list>，保存到Map中
     */
    private Map<Integer, List<ProductCategory>> getMap() {
        // 1. 查询所有数据
        List<ProductCategory> itemCatList = productCategoryMapper.selectList(null);
        // 2. 封装数据到 Map 中
        Map<Integer, List<ProductCategory>> map = new HashMap<>();

        for (ProductCategory itemCat : itemCatList) {
            int parentId = itemCat.getParentId();
            if (map.containsKey(parentId)) { // javadoc 3.1
                map.get(parentId).add(itemCat); // javadoc 3.2
            } else { // javadoc 3.3
                List<ProductCategory> list = new ArrayList<>();
                list.add(itemCat);
                map.put(parentId, list);
            }
        }
        return map;
    }

    private List<ProductCategory> findTwoCatList(Map<Integer, List<ProductCategory>> map) {
        // 1. 获取 一级类别
        List<ProductCategory> oneList = map.get(0);
        // 2. 根据一级 查询二级
        for (ProductCategory itemCat : oneList) {
            List<ProductCategory> twoList = map.get(itemCat.getId());
            itemCat.setChildren(twoList);
        }
        return oneList;
    }

    private List<ProductCategory> findThreeCatList(Map<Integer, List<ProductCategory>> map) {
        List<ProductCategory> oneList = findTwoCatList(map);
        for (ProductCategory itemCat : oneList) { // 1级类别
            if (itemCat.getChildren() != null) {
                for (ProductCategory itemCat2 : itemCat.getChildren()) { // 2级类别
                    List<ProductCategory> threeList = map.get(itemCat2.getId());
                    itemCat2.setChildren(threeList);
                }
            }
        }
        return oneList;
    }
}
